package com.chefu.common.net;

import android.content.Context;
import android.support.annotation.NonNull;


import com.chefu.common.app.Latte;
import com.chefu.common.net.result.OnResultListener;
import com.chefu.common.util.AppUtils;
import com.chefu.common.util.StringUtils;
import com.chefu.common.util.UiUtil;

import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.adapter.rxjava.HttpException;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by xingzhezuomeng on 16/8/8.
 */
public class HttpManager {

    private static final String TAG = "HttpManager";


    //存放网络请求集合
    private List<Call> calls = new ArrayList<>();

    //存放所有订阅者
    private List<Subscription> subscriptions = new ArrayList<>();

    private static HttpManager INSTANCE = null;


    /**
     * 获取 HttpManager 对象
     *
     * @return
     */
    public static HttpManager getManager() {
        if (INSTANCE == null) {
            synchronized (HttpManager.class) {

                if (INSTANCE == null) {
                    INSTANCE = new HttpManager();
                }
            }
        }
        return INSTANCE;
    }


    /***
     * 采用retrofit 请求数据
     *
     * @param call
     * @param onResultListener
     */
    public <T> void loadData(@NonNull Call<T> call, @NonNull final OnResultListener<T> onResultListener) {

        //网络检测
        boolean isNetConnect = AppUtils.checkNetworkStatus(Latte.getApplicationContext());

        if (!isNetConnect) {
            onResultListener.onNetError();
            return;
        }
        calls.add(call);

        call.enqueue(new Callback<T>() {

            @Override
            public void onResponse(Call<T> call, Response<T> response) {

                if (response != null) {
                    T t = response.body();

                    if (t != null) {

                        if (onResultListener != null) {
                            onResultListener.onSuccess(t);
                        }
                    }
                }

            }

            @Override
            public void onFailure(Call<T> call, Throwable t) {

                if (t instanceof HttpException) {
                    HttpException httpException = (HttpException) t;
                    //httpException.response().errorBody().string()
                    int code = httpException.code();
                    String msg = httpException.getMessage();
                    if (code == 504) {
                        msg = "网络不给力";

                        if (onResultListener != null)
                            onResultListener.onNetError();
                    }
                    if (onResultListener != null) {

                        if (StringUtils.isEmpty(msg)) {
                            onResultListener.onFailure(code, "");
                        } else {
                            onResultListener.onFailure(code, msg);
                        }

                    }
                } else if (t instanceof SocketTimeoutException) {
                    onResultListener.onFailure(0, "连接超时");
                } else {
                    if (onResultListener != null) {
                        String errorMsg = t.getMessage();

                        if (StringUtils.isEmpty(errorMsg)) {
                            onResultListener.onFailure(0, "");
                        } else {
                            onResultListener.onFailure(0, errorMsg);
                        }

                    }
                }

            }
        });
    }


    /**
     * 使用rxjava 请求数据 默认处理
     *
     * @param observable
     * @param onResultListener
     * @param <T>
     */
    public <T> void loadData(@NonNull Observable<T> observable, @NonNull final OnResultListener<T> onResultListener) {

        //网络检测
        boolean isNetConnect = AppUtils.checkNetworkStatus(Latte.getApplicationContext());

        if (!isNetConnect) {
            onResultListener.onNetError();
            return;
        }

        Subscription subscription = observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<T>() {

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                        if (e instanceof HttpException) {
                            HttpException httpException = (HttpException) e;
                            //httpException.response().errorBody().string()
                            int code = httpException.code();
                            String msg = httpException.getMessage();
                            if (code == 504) {
                                msg = "网络不给力";

                                onResultListener.onNetError();
                            }
                            onResultListener.onFailure(code, msg);
                        } else {
                            onResultListener.onFailure(0, e.getMessage());
                        }
                    }

                    @Override
                    public void onNext(T t) {

                        onResultListener.onSuccess(t);

                    }
                });

        subscriptions.add(subscription);

    }

    /**
     * rxjava 加载数据自定义处理
     *
     * @param o
     * @param s
     * @param <T>
     */
    public <T> void loadData(Observable<T> o, Subscriber<T> s) {
        Subscription subscription = o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s);

        subscriptions.add(subscription);
    }

    /**
     * 取消请求
     *
     * @param call
     */
    public void clearCall(Call call) {
        if (call != null)
            call.cancel();
    }

    /**
     * 移除全部请求
     */
    public void clearAllCall() {
        for (Call call : calls) {
            if (call != null)
                call.cancel();
        }
        calls.clear();
    }

    /**
     * 销毁所有订阅者
     */
    public void clearAllSubscription() {
        for (Subscription subscription : subscriptions) {
            if (!subscription.isUnsubscribed())
                subscription.unsubscribe();
        }
    }


}
